#include"../include/KeyRecommander.h"
#include"../include/Dictionary.h"
#include"../include/Mylogger.h"
#include<nlohmann/json.hpp>
#include<sstream>
#include<iostream>
//#include<iomanip>

using json = nlohmann::json;
//using namespace nlohmann;
using namespace std;

KeyRecommander::KeyRecommander(const string &dictEn,const string &dictZh, const string &indexEn, const string &indexZh)
{
    Dictionary *ptr = Dictionary::getInstance();
    ptr->init(dictEn,dictZh,indexEn,indexZh);
}

KeyRecommander::~KeyRecommander()
{

}

string KeyRecommander::execute(string &Msg)
{
    //任务队列添加元素
    queryIndexTable(Msg);
    //返回任务队列前5个元素或者NULL
    return response(Msg);
}

void KeyRecommander::queryIndexTable(string &Msg)
{
    string line = Dictionary::getInstance()->doQuery(Msg);
    
    istringstream iss(line);
    string ch;
    while(iss >> ch) {
        statistic(Msg,Dictionary::getInstance()->getIndex()[ch]);
    }

}

void KeyRecommander::statistic(string &Msg,set<int> &iset)
{
    
    for(auto &elem : iset) {
        vector<pair<string, int>> &dict = Dictionary::getInstance()->getDict();
        CandidateResult candidateresult(dict[elem].first, dict[elem].second, distance(Msg,dict[elem].first));
        //cout<<candidateresult._word<<" ";
        _resultQue.push(candidateresult);
    }


}
    //jisuan
int KeyRecommander::distance(string &Msg,const string &rhs)
{
    return Dictionary::getInstance()->editDistance(Msg, rhs);
}

string KeyRecommander::response(string &Msg)
{
    string msg;
    set<string> noReaptedWord;
    vector<string> res;
    cout<<"word:"<<Msg<<endl;


    if (_resultQue.empty())
    {
        cout << "No relevant word!" << endl;
        msg = "null";
        res.push_back(msg);
    }
    else
    {
        cout << "Candidate word:" << endl;
        msg += _resultQue.top()._word;

        res.push_back(_resultQue.top()._word);
        
        /*cout << "Words: " << _resultQue.top()._word << "\tDistance: " << _resultQue.top()._dist << "\tFrequency: " << _resultQue.top()._freq << endl;*/
        noReaptedWord.insert(_resultQue.top()._word);
        _resultQue.pop();
        while (!_resultQue.empty() && noReaptedWord.size() != 5)
        {
            if (noReaptedWord.count(_resultQue.top()._word) == 0)
            {
                res.push_back(_resultQue.top()._word);

                msg += " ";
                msg += _resultQue.top()._word;
                noReaptedWord.insert(_resultQue.top()._word);
                /*cout << "Words: " << _resultQue.top()._word << "\tDistance: " << _resultQue.top()._dist << "\tFrequency: " << _resultQue.top()._freq << endl;
                */
            }
            _resultQue.pop();
        }
        while(!_resultQue.empty())
        {
            _resultQue.pop();
        }
        for(auto s:res)
        {
            cout<<s<<" ";
        }
        cout<<endl;
    }
    string info = "server send to client -->:"+msg;
    LogInfo("%d{%Y-%m-%d %H:%M:%S} %c [%p] %m%n",info.c_str());
    
    json j = res; 
    string msgs = j.dump();
    //加入redis
    cout<<"数据来源文件查询"<<endl;

    LogInfo("%d{%Y-%m-%d %H:%M:%S} %c [%p] %m%n","数据来源 -- 文件");
    MyRedis *redis = MyRedis::getInstance();
    redis->select(0);
    redis->multi();
    redis->set(Msg,msgs);
    redis->exec();
    
    return msgs;
}
